<?php
namespace App\Services\Infra;

use App\Models\Device;
use App\Models\DeviceFault;
use App\Models\DeviceRecord;
use App\Models\InstallInfo;
use App\Models\MaintainInfo;
use App\Models\User;
use App\Models\UserDevice;
use App\Exceptions\DeviceException;
use App\Exceptions\SystemException;
use Cache;
use Carbon\Carbon;
use DB;
use Exception;

class DeviceManager
{
	/**
     * 根据用户获取设备记录
	 * @param  User   $user
	 * @return array 	设备号列表
	 */
	public function getDeviceListByUser($user){
		$user->load(['devices' => function($query){
			$query->select(['id', 'code']);
		}]);
		return $user->devices;
	}

    /**
     * 是否已绑定
     * @param  User   $User
     * @param  string 	设备号
     */
    public function isBound($User, $deviceCode)
    {
    	$device = $this->getDeviceByQuery('code', $deviceCode);
    	if(is_null($device)){
    		throw new DeviceException('noBind');
    	}
    	
    	$record = UserDevice::where('user_id', $User->user_id)->where('device_id', $device->id)->first();
    	if(is_null($record)){
    		throw new DeviceException('noBind');
    	}
    }

    /**
     * 是否已生成记录
     * @param  string  $deviceCode 
     * @return boolean             
     */
    public function isCreateDeviceRecord($deviceCode)
    {
    	$device = $this->getDeviceByQuery('code', $deviceCode);
    	if(is_null($device)){
    		$device = Device::create(['code' => $deviceCode]);
    	}
        return $device;
    }

    /**
     * 根据设备码获取设备
     * @param  string $deviceCode 
     * @return              
     */
    public function getDeviceByQuery($column, $condition)
    {
        $device = Device::where($column, $condition)->first();
    	return $device;
    }

    public function findDeviceByDeviceCode($deviceCode)
    {
        return Device::where('code', 'like', '%'.$deviceCode.'%')->get();
    }

    /**
     * 保存设备信息
     * @param  array  $data 
     * @return        
     */
    public function save($data)
    {
    	$device = $this->getDeviceByQuery('code', $data['device_code']);
    	$data = array_merge($data, [
    		'device_id' => $device->id,
    		]);
        DeviceRecord::create($data);
    }

    /**
     * 根据状态获取全部设备信息包含设备码
     * @param  integer $status 
     * @return          
     */
    public function findDeviceRecordWithCodeByStatus($status, $condition = null)
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');
        $query = DeviceRecord::with(['device' => function($query){
            $query->with(['userInfos' => function($query){
                $query->select('current_device_id', 'name');
            }, 'installInfo' => function($query){
                $query->select('device_code', 'dealer', 'customer_name');
            }])->select('id', 'code', 'status');
        }]);
        // 判断状态不能为空并且有缺水检修漏水停机状态
        if(!empty($status) && in_array($status, [DeviceRecord::HYDROPENIA, DeviceRecord::OVERHAUL, DeviceRecord::LEAKAGE, DeviceRecord::HALT])){
            
        }
        if(!empty($condition)){
            $deviceIds1 = Device::where('code', 'like', '%'.$condition.'%')->select('id')->get();
            $deviceIds2 = $this->findDevicesByCustomerName($condition);
            $query->whereIn('device_id', array_merge($deviceIds1->pluck('id')->toArray(), $deviceIds2->pluck('id')->toArray()));
            
        }
        
        return $query->whereIn('id', $ids)->select([
                                                    'id',
                                                    'device_id',
                                                    'TDS1',
                                                    'TDS2',
                                                    'filter1',
                                                    'filter2',
                                                    'filter3',
                                                    'filter4',
                                                    'filter5',
                                                    'residual_flow',
                                                    'dec_status',
                                                    'created_at',
                                                    'time_limit',
                                                    'amount_water',
                                                    ]);

        
    }

    /**
     * 根据设备码获取所有设备记录并带有设备码
     * @param  integer  $deviceId 
     * @return            
     */
    public function getAllDeviceRecordWithCodeByDeviceCode($deviceId)
    {
        return DeviceRecord::where('device_id', $deviceId)->select([
                                                            'device_id',
                                                            'TDS1',
                                                            'TDS2',
                                                            'filter1',
                                                            'filter2',
                                                            'filter3',
                                                            'filter4',
                                                            'filter5',
                                                            'dec_status',
                                                            'residual_flow',
                                                            'created_at',
                                                            'time_limit',
                                                            'amount_water',
                                                            ])->latest();
    }

    /**
     * 更新设备信息
     * @param  string  $deviceCode 
     * @param  array $data       
     * @param  integer $conExt     
     * @return              
     */
    public function updateDevice($deviceCode, $data, $conExt)
    {
        $device = Device::where('code', $deviceCode)->first();
        if(is_null($device)){
            throw new DeviceException('notFound');
        }
        if(($conExt == 0 && $device->status != Device::STATUS_WORK) || ($conExt == 1 && $device->status != Device::STATUS_HALT)){
            $device->update($data);
        }
    }

    /**
     * 根据 id 获取设备记录
     * @param  integer $id 
     * @return      
     */
    public function getDeviceRecordById($id)
    {
        $deviceRecord = DeviceRecord::where('id', $id)->first();
        if(is_null($deviceRecord)){
            throw new DeviceException('record.notFound');
        }
        return $deviceRecord;
    }

    /**
     * 获取设备提醒记录
     * @param  string  $condition 
     * @return              
     */
    public function getDeviceRemindList($condition)
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');

        $query = DeviceRecord::with(['device' => function($query){
            $query->with(['userInfos' => function($query){
                $query->select('current_device_id', 'name', 'phone');
            }, 'installInfo' => function($query){
                $query->select('device_code', 'customer_name', 'phone', 'installation_address');
            }]);
        }])->whereIn('id', $ids);
        if(!empty($condition)){
            $deviceIds1 = Device::where('code', 'like', '%'.$condition.'%')->select('id')->get();
            $deviceIds2 = $this->findDevicesByCustomerName($condition);
            $query->whereIn('device_id', array_merge($deviceIds1->pluck('id')->toArray(), $deviceIds2->pluck('id')->toArray()));
        }
        return $query;
    }

    /**
     * 添加安装信息
     * @param array $data 
     */
    public function addInstallInfo($data)
    {
        try{
            InstallInfo::create($data);
        }catch(Excption $e){
            throw new SystemException('database');
        }
    }

    /**
     * 根据条件获取安装信息
     * @param string  $column 
     * @param string $data   
     * @return          
     */
    public function getInstallInfoByQueryColumn($column, $data)
    {
        $installInfo = InstallInfo::where($column, $data)->first();
        if(is_null($installInfo) && $column != 'device_code'){
            throw new DeviceException('installInfo.notFound');
        }
        return $installInfo;
    }

    /**
     * 根据条件获取维护信息
     * @param  string $column 
     * @param  string $data   
     * @return          
     */
    public function getMaintainInfoByQueryColumn($column, $data)
    {
        $installInfo = MaintainInfo::where($column, $data)->first();
        dd($installInfo);
        if(is_null($installInfo)){
            throw new DeviceException('maintainInfo.notFound');
        }
        return $installInfo;
    }

    /**
     * 添加维护信息
     * @param array $data 
     */
    public function addMaintainInfo($data)
    {
        try{
            MaintainInfo::create($data);
        }catch(Exception $e){
            dd($e->getMessage());
            throw new SystemException('database');
        }
    }

    /**
     * 获取安装信息
     * @return              
     */
    public function getInstallInfoListBuilderOrderByCreatedAt()
    {
        $query = InstallInfo::latest();
        return $query;
    }
    
    /**
     * 获取维护信息
     * @return              
     */
    public function getMaintainInfoListBuilderOrderBy($column)
    {
        $query = MaintainInfo::orderBy($column);
        
        return $query;
    }

    /**
     * 根据状态对设备提醒记录计数
     * @param  integer $status 
     * @return          
     */
    public function countFlowRemindListByStatus($status)
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');
        $query = DeviceRecord::whereIn('id', $ids)->where(function($query) use ($status){
            $query->where('residual_flow', '<=', 100)->where('flow_status', $status)->whereExists(function($query){
                $query->select('recharge_mode')
                    ->from('devices')
                    ->whereRaw('devices.id = device_records.device_id')
                    ->where('recharge_mode', '=', 2);
            })->orWhere(function($query) use ($status){
                $query->where('time_limit', '<=', 20)->where('flow_status', $status)->whereExists(function($query){
                $query->select('recharge_mode')
                    ->from('devices')
                    ->whereRaw('devices.id = device_records.device_id')
                    ->where('recharge_mode', '=', 1);
                });
            });
        });
        return $query->count();
    }

    /**
     * 根据状态对设备提醒记录计数
     * @param  integer $status 
     * @return          
     */
    public function countFilterRemindListByStatus($status)
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');
        $query = DeviceRecord::whereIn('id', $ids)->where('filter_status', $status)->where(function($query){
            for($i=1; $i<=4; $i++){
                $query->orWhere('filter'.$i, '<=', 15);
            }
        });
        return $query->count();
    }

    public function findmaintainInfoBuilderByColumn($column, $condition)
    {
        return MaintainInfo::where($column, $condition);
    }

    public function getDeviceBuilderOrderByCreatedAt()
    {
        return Device::latest();
    }

    public function getDevicesByDeviceCodeArray($deviceCodeArray)
    {
        return Device::whereIn('code', $deviceCodeArray)->select('id')->get();
    }

    public function findDevicesByCustomerName($customerName)
    {
        $deviceCodes = InstallInfo::where('customer_name', 'like', '%'.$customerName.'%')->select('device_code')->get();
        return $this->getDevicesByDeviceCodeArray($deviceCodes->pluck('device_code'));
    }

    public function getInstallerByQuery($condition)
    {
        return InstallInfo::where('operator', 'like', '%'.$condition.'%')->distinct()->get(['operator','operator_phone']);
    }

    public function getDealerByQuery($condition)
    {
        return InstallInfo::where('dealer', 'like', '%'.$condition.'%')->distinct()->get(['dealer']);
    }

    public function addDeviceFaultRecord($data)
    {
        DeviceFault::create($data);
    }

    public function getDeviceFaultLatestBuilder()
    {
        return DeviceFault::latest();
    }

    public function updateDeviceFaults($deviceId)
    {
        DeviceFault::where('device_id', $deviceId)->delete();
    }

    public function countTdsRemindList()
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');
        $query = DeviceRecord::whereIn('id', $ids)->where('TDS2', '>=', 45);
        return $query->count();
    }

    public function countStatusRemindList()
    {
        $ids = DB::select('select max(id) as id from device_records group by device_id');
        $query = DeviceRecord::whereIn('id', $ids)->whereIn('dec_status', [2, 4, 6, 8, 9]);
        return $query->count();
    }

    public function getDeviceRecordBuilderByQuery($column, $condition)
    {
        return DeviceRecord::where($column, $condition);
    }

}